﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Timers;
using System.Windows.Forms;

namespace LocalizationTest.Tools
{
  class LogPlayer
  {
    ActionAndObservationHistory log = null;
    int counter = 0;
    int oldCounter = 0;
    //    Experiment experiment;
//    MainForm mainForm;
//    bool stillProcessing = false;

    ProgressBar progressBar;

    public LogPlayer(ProgressBar progressBar)
    {
      this.progressBar = progressBar;
    }

/*
    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
      if (stillProcessing) return;
      stillProcessing = true;
      mainForm.firstIndexOfCurrentFrame = experiment.actionAndObservationHistory.history.Count;
      Next(experiment);
      mainForm.Localization();
//      mainForm.InvalidatePanels();
      stillProcessing = false;
    }
    */

    public void Open(Experiment experiment)
    {
      counter = 0;
      experiment.actionAndObservationHistory.Delete();
      log = new ActionAndObservationHistory();
      StreamReader streamReader = new StreamReader(DrawingTools.GetPath() + "test.txt");
      while (!streamReader.EndOfStream)
      {
        string currentLine = streamReader.ReadLine();
        currentLine = currentLine.Replace(" ", "");
        currentLine = currentLine.Replace(".", ",");
        currentLine = currentLine.Replace(":", ": ");
        if (currentLine.StartsWith("state: "))
        {
          string[] parts = currentLine.Replace("state: ", "").Split('|');
          if (parts[0] == "WorldState1D")
          {
            log.Add(new WorldState1D().Parse(parts[1]));
          }
          if (parts[0] == "WorldState2D")
          {
            log.Add(new WorldState2D().Parse(parts[1]));
          }
          if (parts[0] == "WorldStatePose2D")
          {
            log.Add(new WorldStatePose2D().Parse(parts[1]));
          }
        
        }
        if (currentLine.StartsWith("action: "))
        {
          string[] parts = currentLine.Replace("action: ", "").Split('|');
          if (parts[0] == "DiscreteAction2D")
          {
            log.Add(new DiscreteAction2D().Parse(parts[1]));
          }
          if (parts[0] == "ContinuousAction2D")
          {
            log.Add(new ContinuousAction2D().Parse(parts[1]));
          }
          if (parts[0] == "ContinuousActionPose2D")
          {
            log.Add(new ContinuousActionPose2D().Parse(parts[1]));
          }
        }
        if (currentLine.StartsWith("measurement: "))
        {
          string[] parts = currentLine.Replace("measurement: ", "").Split('|');
          if (parts[0] == "DepthMeasurement")
          {
            log.Add(new DepthMeasurement().Parse(parts[1], experiment));
          }
          if (parts[0] == "AngleMeasurement")
          {
            log.Add(new AngleMeasurement().Parse(parts[1], experiment));
          }
          if (parts[0] == "DistanceMeasurement")
          {
            log.Add(new DistanceMeasurement().Parse(parts[1], experiment));
          }
          //measurement: AngleMeasurement|BearingSensor;centerLeftFlag/-0,134510397690539


        }
      }
      streamReader.Close();

    }
    public void Next(Experiment experiment)
    {
      DebugKeyTool.IsActive("log player:limited");

      if (log == null || counter == log.history.Count) return;
      oldCounter = experiment.actionAndObservationHistory.history.Count;
      while (counter != log.history.Count)
      {
        object currentEntry = log.history[counter];
        experiment.actionAndObservationHistory.Add(currentEntry);
        if (currentEntry is WorldState) experiment.simulatedWorldState = currentEntry as WorldState;
        counter++;
        if(counter == log.history.Count) break;
        if((log.history[counter]) is WorldState) break;
      }
      //

      
      //while

    }
    public void Play(MainForm mainForm, Experiment experiment)
    {
    //  DebugDrawingTool.disabeled = true;
      progressBar.Visible = true;
      progressBar.Minimum = counter;
      progressBar.Maximum = log.history.Count;
      int startCounter = counter;
      int maxNumberOfSteps = int.MaxValue;
      if (DebugKeyTool.IsActive("log player:limited"))
      {
        maxNumberOfSteps = 30;
        progressBar.Maximum = counter + maxNumberOfSteps;
      }
      while (counter != log.history.Count && counter - startCounter < maxNumberOfSteps)
      {
        progressBar.Value = counter;
        if (counter % 20 == 0)
        {
          progressBar.Refresh();
          Application.DoEvents();
        }

        DebugDrawingTool.ResetDrawings();

        Next(experiment);

        //DRAW MAP
        if (!DebugKeyTool.IsActive("options view:map - draw last")) experiment.map.Draw();

        //LOCALIZATION
        mainForm.Localization();

        //DRAW MAP
        if (DebugKeyTool.IsActive("options view:map - draw last")) experiment.map.Draw();

        //DRAW WORLDSTATE
        experiment.simulatedWorldState.DrawHighlighted("world:_world state", System.Drawing.Color.Blue);

        //DRAW ALL NEW MEASUREMENTS
        int index = oldCounter;
        while (index >= 0 && index < experiment.actionAndObservationHistory.history.Count)
        {
          if (experiment.actionAndObservationHistory.history[index] is Measurement)
          {
            (experiment.actionAndObservationHistory.history[index] as Measurement).Draw(experiment.simulatedWorldState, 0, "world:_measurement");
          }
          index++;
        }

        //DRAW HISTORY
        experiment.actionAndObservationHistory.Draw(experiment.simulatedWorldState);



        DebugDrawingTool.SaveBitmaps();
        DebugDrawingTool.SaveMetafiles();
      }
      progressBar.Visible = false;
      mainForm.firstIndexOfCurrentFrame = experiment.actionAndObservationHistory.history.Count;
      DebugDrawingTool.state.Disabeled = false;
      /*
            if (timer.Enabled) timer.Stop();
            else timer.Start();
            this.experiment = experiment;
            this.mainForm = mainForm;*/
    }
  }
}
